package com.gitee.qdbp.general.common.web.controller.trade;

import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.result.ResponseMessage;
import com.gitee.qdbp.base.annotation.OperateRecord;
import com.gitee.qdbp.base.enums.OperateType;
import com.gitee.qdbp.base.utils.WebTools;
import com.gitee.qdbp.general.thirdpart.api.alipay.model.AlipayPrepayParams;
import com.gitee.qdbp.general.thirdpart.api.alipay.model.IAlipayConfig;
import com.gitee.qdbp.general.thirdpart.api.alipay.service.IAlipayTradeService;
import com.gitee.qdbp.general.trade.enums.PayChannel;
import com.gitee.qdbp.tools.files.PathTools;
import com.gitee.qdbp.tools.utils.JsonTools;
import com.gitee.qdbp.tools.utils.StringTools;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 支付宝支付流程<br>
 * <pre>
    <font color="red"><b>spring-web.xml</b></font>
    &lt;bean class="com.gitee.qdbp.general.system.web.controller.personnel.BaseAlipayPaymentController" /&gt;
    <font color="red"><b>spring-biz.xml</b></font>
    &lt;bean class="com.gitee.qdbp.general.common.biz.thirdpart.alipay.AlipayConfig"&gt;
        &lt;constructor-arg ref="setting" /&gt;
    &lt;/bean&gt;
    &lt;bean class="com.gitee.qdbp.general.common.biz.thirdpart.alipay.AlipayTradeService" /&gt;
    &lt;bean class="com.gitee.qdbp.general.common.biz.service.XxxPaymentBusinessService" /&gt;
    <font color="red"><b>setting.properties</b></font>
    alipay.app_id = 
    alipay.merchant_private_key = 
    alipay.alipay_public_key = 
    # 如果NotifyUrl是本项目, 则前台传一个相对路径payment/alipay-notify.do
    # 如果NotifyUrl不是本项目, 则前台不传, 在setting.properties配置
    site.xxx.outer.url = http://ip:port/xxx/
    alipay.merchant.notify_url = {config:site.xxx.outer.url}payment/alipay-notify.do
 *  </pre>
 *
 * @author zhaohuihua
 * @version 150915
 */
@RequestMapping()
public class BaseAlipayPaymentController {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    protected IAlipayConfig config;

    @Autowired
    private IAlipayTradeService alipayTradeService;

    /** 发起支付 **/
    @ResponseBody
    @RequestMapping(value = "/payment/alipay-prepay.json")
    @OperateRecord(value = "支付宝支付:发起", type = OperateType.CREATE)
    public ResponseMessage prepayByAjax(AlipayPrepayParams params) {

        handlePrepayParams(params);
        try {
            String form = alipayTradeService.createPagePayForm(params);
            return new ResponseMessage(form);
        } catch (ServiceException e) {
            return new ResponseMessage(e);
        }
    }

    /** 发起支付 **/
    @RequestMapping(value = "/payment/alipay-prepay.do")
    @OperateRecord(value = "支付宝支付:发起", type = OperateType.CREATE)
    public void prepayByHtml(AlipayPrepayParams params, HttpServletResponse response) {

        handlePrepayParams(params);
        String form;
        try {
            form = alipayTradeService.createPagePayForm(params);
        } catch (ServiceException e) {
            return;
        }
        try {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write(form);
        } catch (IOException e) {
            String m = "[WechatPay]NotifyResponseWriteError. \n{}\n{}";
            log.error(m, form, JsonTools.toJsonString(params), e);
            return;
        }
    }

    private void handlePrepayParams(AlipayPrepayParams params) {
        params.setPayChannel(PayChannel.ALIPAY);
        if (VerifyTools.isNotBlank(params.getReturnUrl()) && !StringTools.isUrl(params.getReturnUrl())) {
            params.setReturnUrl(getWebUrl(params.getReturnUrl()));
        }
        if (VerifyTools.isNotBlank(params.getNotifyUrl()) && !StringTools.isUrl(params.getNotifyUrl())) {
            params.setNotifyUrl(getWebUrl(params.getNotifyUrl()));
        }
    }

    private String getWebUrl(String uri) {
        if (uri == null || StringTools.isUrl(uri)) {
            return uri;
        }

        String prefix = config.getPaymentUrlPrefix();
        if (VerifyTools.isBlank(prefix)) {
            return WebTools.me.getWebUrl(uri);
        } else {
            if (uri.startsWith("/")) {
                // prefix和uri都带工程名
                String ctxPath = WebTools.me.getContextPath();
                if (VerifyTools.isNotBlank(ctxPath) && uri.startsWith(ctxPath)) {
                    uri = uri.substring(ctxPath.length());
                }
                return PathTools.concat(prefix, uri);
            } else {
                return PathTools.concat(prefix, uri);
            }
        }
    }

    /** 支付回调通知 **/
    @RequestMapping("/payment/alipay-notify")
    @OperateRecord(value = "支付宝支付:回调", type = OperateType.UPDATE)
    public void notify(HttpServletRequest request, HttpServletResponse response) {

        // 获取支付宝POST过来的反馈信息
        Map<String, String> params = new WebTools(request).getRequestParams();
        String text = alipayTradeService.notifyHandle(params);
        try {
            response.getWriter().write(text);
        } catch (IOException e) {
            String m = "[WechatPay]NotifyResponseWriteError. {}\n\t{}";
            log.error(m, text, JsonTools.toJsonString(params), e);
        }
    }
}
